import axios from 'axios'
import type { AxiosInstance, AxiosResponse, AxiosError } from 'axios'
import { showToast } from 'vant'
import type { ApiResponse } from '../types/api'

// 创建axios实例
const apiClient: AxiosInstance = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api/v1',
    timeout: 10000,
    headers: {
        'Content-Type': 'application/json',
    },
})

// 请求拦截器
apiClient.interceptors.request.use(
    (config) => {
        // 添加认证token
        const token = localStorage.getItem('token')
        if (token) {
            config.headers.Authorization = `Bearer ${token}`
        }

        // 添加请求时间戳
        config.metadata = { startTime: new Date() }

        return config
    },
    (error: AxiosError) => {
        console.error('Request error:', error)
        return Promise.reject(error)
    }
)

// 响应拦截器
apiClient.interceptors.response.use(
    (response: AxiosResponse<ApiResponse>) => {
        // 计算请求耗时
        const endTime = new Date()
        const startTime = response.config.metadata?.startTime
        if (startTime) {
            const duration = endTime.getTime() - startTime.getTime()
            console.log(`API ${response.config.method?.toUpperCase()} ${response.config.url} took ${duration}ms`)
        }

        // 返回完整的响应对象
        return response
    },
    (error: AxiosError<ApiResponse>) => {
        const { response } = error

        // 处理不同的错误状态码
        if (response && response.status === 401) {
            // Token过期或无效，清除本地存储并跳转到登录页
            localStorage.removeItem('token')
            localStorage.removeItem('user')
            showToast('Login expired, please login again')

            // 避免在登录页面重复跳转
            if (window.location.pathname !== '/login') {
                window.location.href = '/login'
            }
        } else if (response && response.status === 403) {
            showToast('No permission to access this resource')
        } else if (response && response.status === 404) {
            showToast('Requested resource not found')
        } else if (response && response.status === 422) {
            // 表单验证错误
            const errorMessage = response.data?.error?.message || 'Invalid input data'
            showToast(errorMessage)
        } else if (response && response.status === 429) {
            showToast('Too many requests, please try again later')
        } else if (response && response.status >= 500) {
            showToast('Server error, please try again later')
        } else if (error.code === 'ECONNABORTED') {
            showToast('Request timeout, please check network connection')
        } else if (error.message === 'Network Error') {
            showToast('Network connection failed, please check network')
        } else {
            // 显示服务器返回的错误信息
            const errorMessage = response?.data?.error?.message || response?.data?.message || 'Request failed'
            showToast(errorMessage)
        }

        return Promise.reject(error)
    }
)

// 扩展axios配置类型以支持metadata
declare module 'axios' {
    interface AxiosRequestConfig {
        metadata?: {
            startTime: Date
        }
    }
}

// 创建包装的API客户端，自动提取data
const wrappedApiClient = {
    get: async <T = any>(url: string, config?: any): Promise<T> => {
        const response = await apiClient.get<T>(url, config)
        // 如果响应数据有 data 属性，提取它；否则返回整个响应数据
        const responseData = response.data as any
        return responseData?.data !== undefined ? responseData.data : responseData
    },
    post: async <T = any>(url: string, data?: any, config?: any): Promise<T> => {
        const response = await apiClient.post<T>(url, data, config)
        const responseData = response.data as any
        return responseData?.data !== undefined ? responseData.data : responseData
    },
    put: async <T = any>(url: string, data?: any, config?: any): Promise<T> => {
        const response = await apiClient.put<T>(url, data, config)
        const responseData = response.data as any
        return responseData?.data !== undefined ? responseData.data : responseData
    },
    patch: async <T = any>(url: string, data?: any, config?: any): Promise<T> => {
        const response = await apiClient.patch<T>(url, data, config)
        const responseData = response.data as any
        return responseData?.data !== undefined ? responseData.data : responseData
    },
    delete: async <T = any>(url: string, config?: any): Promise<T> => {
        const response = await apiClient.delete<T>(url, config)
        const responseData = response.data as any
        return responseData?.data !== undefined ? responseData.data : responseData
    }
}

export default wrappedApiClient